package com.mypaper.main;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import com.mypaper.dag.DAG;
import com.mypaper.dag.DAGGenerator;
import com.mypaper.list.ListPriority;
import com.mypaper.schedule.HEFTSchedule;
import com.mypaper.schedule.HLDSchedule;
import com.mypaper.schedule.OptimizeSchedule;
import com.mypaper.schedule.RDDProSchedule;
import com.mypaper.schedule.RDDSchedule;


public class ScheduleMain {
	public static void main(String[] args) throws FileNotFoundException{	
		//Group 1
		short procNum=4,vertexNum=13;
			float[][] vertexWeight={{3,2,1,2},//1
					{1,3,1,3},//2
					{2,1,3,2},//3
					{2,3,4,1},//4
					{1,1,1,1},//5
					{5,8,7,4},//6
					{2,1,2,3},//7
					{4,3,2,3},//8
					{1,3,2,2},//9
					{6,3,4,7},//10
					{2,1,3,2},//11
					{2,3,4,2},//12
					{2,1,2,3}};//13
			float[][] edgeWeight={{0,0,4,2,0,0,0,0,0,0,0,0,0},
					{0,0,1,0,0,0,0,6,0,0,0,0,0},
					{0,0,0,0,2,0,9,0,0,0,0,0,0},
					{0,0,0,0,1,5,2,1,0,0,0,0,0},
					{0,0,0,0,0,0,0,0,3,0,0,0,0},
					{0,0,0,0,0,0,0,0,2,2,4,0,0},
					{0,0,0,0,0,0,0,0,0,3,0,8,0},
					{0,0,0,0,0,0,0,0,0,0,7,9,0},
					{0,0,0,0,0,0,0,0,0,0,0,0,4},
					{0,0,0,0,0,0,0,0,0,0,0,0,1},
					{0,0,0,0,0,0,0,0,0,0,0,0,1},
					{0,0,0,0,0,0,0,0,0,0,0,0,0},
					{0,0,0,0,0,0,0,0,0,0,0,0,0}};
		/*short procNum=4, vertexNum=10;
		float[][] vertexWeight={{71,47,36,2},
			{78,41,75,61},
			{42,89,34,42},
			{68,70,51,76},
			{29,66,3,12},
			{57,86,45,69},
			{13,80,39,33},
			{47,69,16,61},
			{91,3,3,27},
			{47,81,5,21}};
		float[][] edgeWeight={{0,112,74,0,0,0,0,0,0,0},
				{0,0,0,64,0,0,0,0,0,0},
				{0,0,0,0,84,0,0,0,0,0},
				{0,0,0,0,0,0,65,0,30,0},
				{0,0,0,0,0,118,0,191,0,0},
				{0,0,0,0,0,0,35,5,0,0},
				{0,0,0,0,0,0,0,0,0,11},
				{0,0,0,0,0,0,0,0,0,123},
				{0,0,0,0,0,0,0,0,0,6},
				{0,0,0,0,0,0,0,0,0,0}};*/
		/*short procNum=4, vertexNum=10;
		float[][] vertexWeight=	{{38,36,13,83},
				{17,12,54,15},
				{46,18,88,30},
				{17,84,75,3},
				{30,3,79,10},
				{76,34,37,47},
				{30,71,41,8},
				{64,16,76,14},
				{24,73,49,58},
				{7,89,12,95}};	
		float[][] edgeWeight={{0,18,75,71,0,0,66,0,0,0},
			{0,0,0,0,73,34,0,0,0,0},
			{0,0,0,0,0,19,0,0,0,0},
			{0,0,0,0,0,99,0,0,0,0},
			{0,0,0,0,0,0,0,14,25,0},
			{0,0,0,0,0,0,0,0,1,0},
			{0,0,0,0,0,0,0,0,0,58},
			{0,0,0,0,0,0,0,0,0,41},
			{0,0,0,0,0,0,0,0,0,86},
			{0,0,0,0,0,0,0,0,0,0}};*/
		
		/*short procNum=4, vertexNum=10;
		float[][] vertexWeight={{6,89,22,75},
				{90,71,6,16},
				{63,89,70,35},
				{27,6,20,3},
				{8,40,63,76},
				{81,97,61,55},
				{7,49,18,90},
				{85,43,86,10},
				{79,73,31,81},
				{20,18,77,15}};;
		float[][] edgeWeight={{0,78,12,0,0,0,0,2,0,0},
				{0,0,0,0,26,0,0,0,0,0},
				{0,0,0,63,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,81,0},
				{0,0,0,0,0,27,68,0,0,0},
				{0,0,0,0,0,0,0,0,0,30},
				{0,0,0,0,0,0,0,0,0,58},
				{0,0,0,0,0,0,0,0,0,8},
				{0,0,0,0,0,0,0,0,0,71},
				{0,0,0,0,0,0,0,0,0,0}};*/
		
		/*short procNum=4, vertexNum=15;
		float[][] vertexWeight={{39,46,97,30},
				{89,22,36,41},
				{19,96,23,59},
				{50,49,18,18},
				{16,90,93,14},
				{71,90,35,26},
				{90,47,79,38},
				{36,44,39,86},
				{40,4,83,83},
				{5,63,87,63},
				{45,58,85,7},
				{56,94,80,72},
				{18,22,32,55},
				{37,7,27,94},
				{83,21,47,70}};
		float[][] edgeWeight={{0,37,15,99,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,10,0,0,80,0,0,0,0,0,0},
				{0,0,0,0,30,0,0,93,0,0,0,0,0,0,0},
				{0,0,0,0,47,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,8,0,0,0,0,20,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,73,43,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,37,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,41,98,0,0,0},
				{0,0,0,0,0,0,0,0,0,69,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,1,68,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,75,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,71,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,71},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,31},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};*/
		
		/*short procNum=4, vertexNum=20;
		float[][] vertexWeight={{77,84,80,45},
				{32,45,62,93},
				{40,14,87,85},
				{44,75,47,22},
				{91,63,16,49},
				{95,8,54,71},
				{73,79,48,16},
				{27,52,93,56},
				{82,91,8,4},
				{52,33,12,43},
				{24,32,96,55},
				{97,68,16,77},
				{18,48,30,15},
				{67,89,12,55},
				{21,28,52,28},
				{89,41,92,13},
				{44,19,17,85},
				{94,26,2,45},
				{70,41,56,70},
				{76,58,71,50}};
		float[][] edgeWeight={{0,28,86,0,0,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,74,11,0,67,0,0,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,66,0,0,13,16,0,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,91,0,54,48,0,61,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,13,0,0,45,90,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,75,2,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,1,0,0,0,4,3,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,63,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,0,37,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; */
		
		/*short vertexNum=10, procNum=4;
			
		float[][] vertexWeight={{50,70,33,84},
{17,17,33,28},
{9,8,18,5},
{81,29,81,57},
{47,29,28,84},
{58,31,13,19},
{32,46,18,73},
{65,81,73,69},
{21,92,36,89},
{12,71,39,86}};


		
		float[][] edgeWeight={{0,38,1,0,0,0,0,0,0,0},
				{0,0,0,14,0,0,0,0,0,0},
				{0,0,0,73,54,0,0,0,0,0},
				{0,0,0,0,0,33,35,44,0,0},
				{0,0,0,0,0,0,62,0,0,0},
				{0,0,0,0,0,0,0,0,0,58},
				{0,0,0,0,0,0,0,0,0,78},
				{0,0,0,0,0,0,0,0,5,75},
				{0,0,0,0,0,0,0,0,0,51},
				{0,0,0,0,0,0,0,0,0,0}};*/
		
		/*short procNum=4,vertexNum=10;
		float[][] vertexWeight={{87,81,65,35},
				{4,39,8,35},
				{80,38,17,93},
				{21,95,7,74},
				{6,58,21,78},
				{37,27,22,17},
				{55,52,33,41},
				{67,79,66,59},
				{14,89,78,59},
				{93,27,17,48}};
		float[][] edgeWeight={{0,94,25,0,0,0,0,0,0,0},
				{0,0,0,0,96,2,0,0,0,0},
				{0,0,0,32,0,7,0,0,0,0},
				{0,0,0,0,0,0,0,83,0,0},
				{0,0,0,0,0,0,0,95,0,0},
				{0,0,0,0,0,0,68,0,48,0},
				{0,0,0,0,0,0,0,27,0,0},
				{0,0,0,0,0,0,0,0,0,58},
				{0,0,0,0,0,0,0,0,0,43},
				{0,0,0,0,0,0,0,0,0,0}};*/
		
		/*FileOutputStream fos=new FileOutputStream("yu.txt"); //利用字符流把s写入yu.txt中
		OutputStreamWriter osw=new OutputStreamWriter(fos);*/
		FileOutputStream fos=null;
		OutputStreamWriter osw;
		int count=0;
		DAGGenerator dg=null;
		while(count<1){
		boolean flag=true;
		//while(flag==true){
			/*System.out.println("count="+count);
			if(count==0){
				fos=new FileOutputStream("yu0_2.txt");
			}else if(count==50){
				fos=new FileOutputStream("yu0_5.txt");
			}else if(count==100){
				fos=new FileOutputStream("yu2.txt");
			}else if(count==150){
				fos=new FileOutputStream("yu5.txt");
			}else if(count==200){
				fos=new FileOutputStream("yu1.txt");
			}
			if(count<50){
				dg=new DAGGenerator(16, 300, 0.2f,1);
			}
			else if(count<100){
				dg=new DAGGenerator(16, 300,0.5f,1);		
			}
			else if(count<150){
				dg=new DAGGenerator(16, 300, 1, 1);
			}
			else if(count<200){
				dg=new DAGGenerator(16, 300, 2,1);			
			}
			else if(count<250){
				dg=new DAGGenerator(16, 300,5,1);		
			}*/
			
			
			fos=new FileOutputStream("yu0_2.txt");
			osw=new OutputStreamWriter(fos);
			
			//dg=new DAGGenerator(8, 20, 1, 1);
			
			/*short procNum=(short) dg.PROCNUM, vertexNum=(short)dg.TASKNUM;
			float[][] vertexWeight=dg.comp;
			float[][] edgeWeight=dg.comm;*/
			
			/*System.out.println("vertexWeight:");
			for(int i=0; i<vertexNum; i++){
				for(int j=0; j<procNum; j++){
					System.out.print(vertexWeight[i][j]+"  ");
				}
				System.out.println();
			}
			System.out.println();
			
			System.out.println("edgeWeight:");
			for(int i=0; i<vertexNum; i++){
				for(int j=0; j<vertexNum; j++){
					System.out.print(edgeWeight[i][j]+"  ");
				}
				System.out.println();
			}
			System.out.println();*/
				
			
			DAG dag=new DAG(vertexNum,procNum,vertexWeight,edgeWeight);	
			dag.calcBLPrior();
			ListPriority prior=dag.prior;
			dag.calcHCPrior();
			ListPriority priorHCP=dag.priorHCP;
			prior.print();
			//HEFT算法
			float lowerResourse=0;
			for(int i=0; i<vertexNum; i++){
				float minWeightProc=Float.MAX_VALUE;
				for(int j=0; j<procNum; j++){
					if(minWeightProc>vertexWeight[i][j]){
						minWeightProc=vertexWeight[i][j];
					}
				}
				lowerResourse+=minWeightProc;
			}
			//prior.print();
			 //System.out.println("count="+count);
			HEFTSchedule heftSchedule=new HEFTSchedule(dag);//初始化
			heftSchedule.HEFT_Algorithm(dag);//调度
			float makespanHEFT=heftSchedule.makespan();//求makespan
			System.out.println("The makespan of HEFT is "+makespanHEFT);
			//HLD算法
			
			HLDSchedule hldSchedule=new HLDSchedule(vertexNum,procNum);//初始化调度	
			hldSchedule.HLD_Algorithm(vertexNum,procNum,prior,vertexWeight,edgeWeight);
			int duplNum_HLD=hldSchedule.duplNums(vertexNum);
			float makespanHLD=hldSchedule.makespan();
			///System.out.println("The makespan of HLD is "+makespanHLD);
			float timeHLD=hldSchedule.timeCal(procNum);
			
			/*HCPFDSchedule hcpfdSchedule=new HCPFDSchedule(vertexNum, procNum);
			hcpfdSchedule.HCPFD_Algorithm(vertexNum,procNum,priorHCP,vertexWeight,edgeWeight);
			float makespanHCPFD=hcpfdSchedule.makespan();
			System.out.println("The makespan of HCPFD is "+makespanHCPFD);
			float timeHCP=hcpfdSchedule.timeCal(procNum);
			System.out.println();*/
			
			//long start=System.currentTimeMillis();
			RDDSchedule rddSchedule=new RDDSchedule(vertexNum,procNum,dag);//初始化调度	
			rddSchedule.RDD_Algorithm(vertexNum,procNum,prior,vertexWeight,edgeWeight,dag);
			float makespanRDD=rddSchedule.makespan();
			int duplNum_RDD=rddSchedule.duplNums(vertexNum);
			System.out.println("The makespan of RDD is "+makespanRDD);
			float timeRDD=rddSchedule.timeCal(procNum);
			/*long end=System.currentTimeMillis();
			long costtime   =   end   -   start; 
			System.out.println("costtime="+costtime);
			System.out.println();*/
			
			RDDProSchedule rddProSchedule=new RDDProSchedule(vertexNum, procNum, dag);//初始化调度	
			rddProSchedule.RDDPro_Algorithm(vertexNum,procNum,prior,vertexWeight,edgeWeight,dag);
			float makespanRDDPro=rddProSchedule.makespan();
			int duplNum_RDDRro=rddProSchedule.duplNums(vertexNum);
			System.out.println("The makespan of RDDPro is "+makespanRDDPro);
			float timeRDDPro=rddProSchedule.timeCal(procNum);
			
			//OptimizeSchedule_back optSchedule=new OptimizeSchedule_back(dag.priorRever, dag.prior, rddSchedule, procNum, vertexNum);
			OptimizeSchedule optSchedule=new OptimizeSchedule(dag,dag.priorRever, dag.prior, rddSchedule, procNum, vertexNum);
			optSchedule.Optimize_Schedule(vertexNum, procNum, vertexWeight, edgeWeight, makespanRDD);
			//optSchedule.printSchedule(procNum, vertexNum);
			float makespanOpti=optSchedule.makespan(procNum);
			int duplNum_Opt=optSchedule.duplNums(vertexNum);
			System.out.println("The makespan of optimal is "+makespanOpti);
			float timeOpt=optSchedule.timeCal(procNum);
	
		
			OptimizeSchedule opt2Schedule=new OptimizeSchedule(dag,dag.priorRever, dag.prior, rddProSchedule, procNum, vertexNum);
			opt2Schedule.Optimize_Schedule(vertexNum, procNum, vertexWeight, edgeWeight, makespanRDDPro);
			//optSchedule.printSchedule(procNum, vertexNum);
			float makespanOpti2=optSchedule.makespan(procNum);
			int duplNum_Opt2=optSchedule.duplNums(vertexNum);
			System.out.println("The makespan of optimal2 is "+makespanOpti2);
			float timeOpt2=optSchedule.timeCal(procNum);
			
			//String s=String.valueOf(makespanHEFT+" "+lowerResourse+" "+makespanHLD+" "+timeHLD+" "+makespanRDD+" "+timeRDD+" "+makespanOpti+" "+timeOpt+"\n");       //把sum转化为字符
			String s=String.valueOf(makespanHEFT+" "+lowerResourse+" "+makespanHLD+" "+timeHLD+" "+makespanRDD+" "+timeRDD+" "+makespanRDDPro+" "+timeRDDPro+" "+makespanOpti+" "+timeOpt+" "+makespanOpti+" "+timeOpt+" "+duplNum_HLD+" "+duplNum_RDD+" "+duplNum_RDDRro+" "+duplNum_Opt+"\n");
			/*if(makespanHEFT<makespanHLD){
				flag=false;
			}*/
			try{
				osw.write(s);	
				osw.flush();
				}catch(Exception e){}//结果在文本文档中显示不出来*/
				count++;
				
				/*if(makespanHEFT<makespanHLD){
					flag=false;
				}*/
			}
		}
	}
